/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.playground.client.websockets.application.boardgame;

import com.playground.client.websockets.application.RoomApplication;
import com.playground.client.websockets.entity.message.Action;
import com.playground.client.websockets.entity.message.request.MakeMoveRequestMessage;
import com.playground.client.websockets.entity.message.request.RequestMessage;
import com.playground.client.websockets.entity.message.response.BoardGameStartResponseMessage;
import com.playground.client.websockets.socket.PlayerSocket;
import com.playground.client.websockets.util.JsonUtil;
import com.playground.core.entity.LoggedPlayer;
import com.playground.core.entity.Player;
import com.playground.core.entity.Room;
import com.playground.core.entity.boardgame.BoardGame;
import com.playground.core.entity.boardgame.Move;
import com.playground.core.repository.RoomRepository;
import com.playground.core.service.LoginService;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Tiago Peres
 */
public abstract class BoardGameApplication extends RoomApplication {
    
    public BoardGameApplication(LoginService loginService, RoomRepository roomRepository){
        super(loginService, roomRepository);
    }
    
    // TODO:
    @Override
    public boolean parseMessage(PlayerSocket socket, RequestMessage message){
        if (super.parseMessage(socket, message)){
            // if a new move was requested call executeMovement
            if(Action.makeMove.equals(message.getAction())){
                System.out.println("Make move from " + ((MakeMoveRequestMessage) message).getSourceSquarePosition() + " to " + ((MakeMoveRequestMessage) message).getDestinationSquarePosition() + " requested.");
                try{
                    // for safety: a move cannot start if there's another move being executed
                    synchronized(this){
                        Move move =  new Move();
                        BoardGame game = (BoardGame) socket.getPlayer().getRoom().getGame();
                        MakeMoveRequestMessage msg = (MakeMoveRequestMessage) message;
                        move.setSource(game.getBoard().getSquareAt(msg.getSourceSquarePosition()));
                        move.setDestination(game.getBoard().getSquareAt(msg.getDestinationSquarePosition()));
                        executeMove(socket, move);
                    }
                }
                catch(Exception e){
                    System.out.println("!!!!!!!!!!!!!!!AN EXCEPTION!");
                    e.printStackTrace();
                }
            }
            return true;
        }
        return false;
    }
    
    protected abstract void executeMove(PlayerSocket socket, Move move);
    
    @Override
    protected void informGameStart(Room room){
        try{
        BoardGameStartResponseMessage response = new BoardGameStartResponseMessage();
        response.setSuccess(true);
        List<LoggedPlayer> loggedPlayers = room.getGame().getPlayers();
        List<Player> players = new ArrayList<Player>();
        for (LoggedPlayer p : loggedPlayers){
            LoggedPlayer copy = new LoggedPlayer(p.getId(), null);
            copy.setFacebookId(p.getFacebookId());
            copy.setNickname(p.getNickname());
            players.add(copy);
        }
        
        response.setPlayers(players);
        sendToAll(room, JsonUtil.getGson().toJson(response, BoardGameStartResponseMessage.class));
        informTurn(getPlayerSocketByPlayerId(((BoardGame) room.getGame()).getPlayerInTurn().getId()));        
        } catch(Exception e){
            e.printStackTrace();
        }
    }
    
    protected abstract void informTurn(PlayerSocket socket);
}
